# -*- coding:utf-8 -*-
import re
import logging
import time
from django.utils import simplejson as json
from BeautifulSoup import BeautifulSoup
from CyworldUrl import CyworldUrl

class Cyworld:
    def __init__(self, id = None, tid = None, email = None, password = None):
        self.url = CyworldUrl(id, tid, email, password)
        self.tid = self.url.get_tid()
            
    def get_tid(self):
        return self.tid
        
    def _get_url_as_json(self, url, referer = None, params = None):
        return json.load(self.url.open(url, referer, params), 'cp949')
    
    def get_photo_folder_list(self):
        return self._get_url_as_json('http://minihp.cyworld.com/svcs/Image.cy/FolderView/%s?level=1&urlstr=phot&slide_cnt=20' % self.tid, 'http://minihp.cyworld.com/svcs/Image.cy/Folder/%s?urlstr=phot' % self.tid)
    
    def get_photo_list_generator(self, photo_):
        page = 1
        while True:
            logging.debug("Getting photo list page %d" % page)
            list = self._get_photo_list(photo_, page)
            if list is None or len(list) == 0:
                logging.warn("Empty list.")
                return
            for row in list:
                parser = _PhotoItem(row)
                yield {
                       'image': parser.get_image(),
                       'title': parser.get_title(),
                       'body': parser.get_body(),
                       'author': parser.get_author(),
                       'created': parser.get_created(),
                       'source': parser.get_source(),
                       'visibility': parser.get_visibility(),
                       'comments': parser.get_comments(),
                }
            page += 1
            
    def _get_photo_list(self, id, page):
        f = self.url.open('http://minihp.cyworld.com/svcs/Image.cy/Detail/%s?board_no=%s&urlstr=phot&cpage=%s' % (self.tid, id, page), 'http://minihp.cyworld.com/svcs/Image.cy/Folder/%s?urlstr=phot' % self.tid)
        soup = BeautifulSoup(f.read())
        if soup.find('div',{'class': 'srTemp pcTemp'}):
            logging.debug("No more photo list. Stop iteration.")
            return None
        return soup.findAll('div', {'class': 'mhpw-by'})
    
    def get_diary_folder_list(self):
        f = self.url.open('http://minihp.cyworld.com/svcs/MiniHp.cy/diary/%s?tid=%s&urlstr=diar&seq=' % (self.tid, self.tid), 'http://minihp.cyworld.com/svcs/MiniHp.cy/index/%s?tid=%s&urlstr=&f=&gate=_top' % (self.tid, self.tid))
        soup = BeautifulSoup(f.read().decode('cp949'))
        result = []
        for item in soup.findAll('a', id=re.compile('foldernm_m')):
            result.append({'id': int(item['id'].replace('foldernm_m', '')), 'name': item.text})
        return result
    
    def get_diary_list_generator(self, id):
        f = self.url.open('http://minihp.cyworld.com/pims/diary5/mydiary/diary5_mydiary_itemview.asp?tid=%s&urlstr=diar&list_type=2&folder_no=%s' % (self.tid, id))
        while True:
            parser = _DiaryItem(BeautifulSoup(f.read()))
            yield {
                   'created': parser.get_created(),
                   'visibility': parser.get_visibility(),
                   'body': parser.get_body(),
                   'comments': parser.get_comments(),
            }
            next = parser.get_next()
            if next is None:
                break
            f = self.url.open('http://minihp.cyworld.com/pims/diary5/mydiary/diary5_mydiary_itemview.asp?tid=%s&Toyearmonday=%s&list_type=2&folder_no=%s&cpage=1&search_type=&search_keyword=' % (self.tid, next, id))

class _Item:
    def __init__(self, row):
        self.row = row

    def _parse_time(self, datestring, format):
        return time.mktime(time.strptime(datestring, format)) + 32400 #KST offset
    
    def _parse_datetime(self, datestring):
        return self._parse_time(datestring,"%Y.%m.%d %H:%M")
    
    def _parse_date(self, datestring):
        return self._parse_time(datestring,"%Y.%m.%d")
    
    def get_comments(self):
        result = []
        for row in self.row.findAll('tr', id=re.compile(r'^reply')):
            result.append({
                           'name': row.find('span', id=re.compile(r'^replyWriterNm')).text,
                           'body':row.find('span', id=re.compile(r'^comment')).text,
                           'created': row.find('span', {'class':'date'}).text[1:-1].strip()
            })
        return result
    
    def clean_body(self, body):
        [trash.extract() for trash in body.findAll('script')]
        [trash.extract() for trash in body.findAll('style')]
        return body
    
class _DiaryItem(_Item):
    def get_next(self):
        next = self.row.find('a', {'class': 'btn-href pagedn-on'})
        if next:
            return next['href'].split(',')[2][15:23]
        return None
    
    def get_created(self):
        date_part = self.row.find('em', {'class': 'now-date'})
        return self._parse_datetime(date_part.text.replace(date_part.span.text, ' '))
    
    def get_body(self):
        return self.clean_body(self.row.find('div', {'class':'diary-content'}))
    
    def get_visibility(self):
        return 'public' if self.row.find('span', {'id': 'bopenText0'}).text == u'전체공개' else 'private'
    
        
class _PhotoItem(_Item):
    def get_image(self):
        div = self.row.find('div', {'class': 'mhp-pic'}) 
        return (div.img['realsrc'] if div.img.has_key('realsrc') else div.img['src']) if div.img is not None else div.find('span', {'name': 'flashObj'}).div['flashpath']
    
    def get_title(self):
        return self.row.h3.text
    
    def get_author(self):
        return self.row.find('dd', {'class': 'write'}).text
    
    def get_created(self):
        return self._parse_datetime(self.row.find('dd', {'class': 'date'}).text)
    
    def get_body(self):
        return self.clean_body(self.row.find('div', {'id': 'article-body'}))

    def get_source(self):
        info = self.row.find('dl',{'class': 'atc-detail-info'})
        source_from = info.find('dd', {'class': 'from'}).text
        return None if source_from is None else {
                'from': source_from,
                'author': info.find('dd', {'class': 'writer'}).text,
                'created': self._parse_date(info.find('dd', {'class': 'date'}).text),
        }
    
    def get_visibility(self):
        return 'public' if self.row.find('span', {'class': 'permit'}).text == u'전체공개' else 'private'